/*
 * Copyright (C) 2018 guomw.Inc. All rights reserved.
 * 项目名称： report-manage
 * 文件名称： MvcConfig.java
 * Date：18-11-5 上午11:10
 * Author: guomw
 */

package com.guomw.report.web.config;

import com.guomw.report.common.config.Constant;
import com.guomw.report.service.resolver.OperatorIdArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import java.util.Arrays;
import java.util.List;

/**
 * @author guomw
 */
@Configuration
@EnableWebMvc
@ComponentScan({
        "com.guomw.report.web.controller",
        "com.guomw.report.service.service"
})
public class MvcConfig extends WebMvcConfigurerAdapter {
    /**
     * 静态资源处理,加在这里
     */
    private static String[] STATIC_RESOURCE_PATH = {
            "resource",
            "script"
    };
    @Autowired
    private Environment environment;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Bean
    public AppInterceptor appInterceptor() {
        return new AppInterceptor();
    }

    @Bean
    public UserInterceptor userInterceptor() {
        return new UserInterceptor();
    }

    @Bean
    public FunctionAuthorityInterceptor functionAuthorityInterceptor() {
        return new FunctionAuthorityInterceptor();
    }

    @Bean
    public RefererInterceptor refererInterceptor() {
        return new RefererInterceptor();
    }

    @Autowired
    private OperatorIdArgumentResolver operatorIdArgumentResolver;
    @Bean
    public OperatorIdArgumentResolver operatorIdArgumentResolver() {
        return new OperatorIdArgumentResolver();
    }


    /**
     * 禁止拦截静态资源
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        super.addResourceHandlers(registry);
        for (String resourcePath : MvcConfig.STATIC_RESOURCE_PATH) {
            registry.addResourceHandler("/" + resourcePath + "/**").addResourceLocations("/" + resourcePath + "/");
        }
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);

        /**
         * 利用referer实现安全防盗链
         */
        registry.addInterceptor(refererInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/api/**", "/login", "/", "/bank", "/index", "/home","/activity/lucky/**")
        ;

        //接口请求拦截
        registry.addInterceptor(appInterceptor())
                .addPathPatterns("/api/**");

        //页面访问权限拦截
        registry.addInterceptor(userInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/api/**", "/login", "/doLogin", "/index", "/logout", "/", "/*/ajax/**", "/bank", "/verifyCode","/activity/lucky/**","/user/viewReport");


        //页面功能权限拦截，作用：判断当前用户是否有该功能的操作权限
        registry.addInterceptor(functionAuthorityInterceptor())
                .addPathPatterns("/*/ajax/**")
                .excludePathPatterns("/api/**", "/sys/ajax/leftlist", "/sys/ajax/upload","/activity/lucky/**");

    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(operatorIdArgumentResolver);
    }

    /**
     * 视图显示Resolver
     *
     * @param registry
     */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        super.configureViewResolvers(registry);
        registry.viewResolver(viewResolver());
    }

    /**
     * thymeleaf解析
     *
     * @return
     */
    @Bean
    public ThymeleafViewResolver viewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        SpringTemplateEngine engine = new SpringTemplateEngine();
        ServletContextTemplateResolver rootTemplateResolver = new ServletContextTemplateResolver(webApplicationContext.getServletContext());
        rootTemplateResolver.setPrefix("/views/");
        rootTemplateResolver.setSuffix(".html");
        rootTemplateResolver.setTemplateMode(TemplateMode.HTML);
        rootTemplateResolver.setCharacterEncoding("UTF-8");
        if (environment.acceptsProfiles(Constant.PROFILE_DEV)) {
            rootTemplateResolver.setCacheable(false);
        }
        engine.setTemplateResolver(rootTemplateResolver);
        resolver.setTemplateEngine(engine);
        resolver.setOrder(100);
        resolver.setCharacterEncoding("UTF-8");
        resolver.setContentType("text/html;charset=utf-8");
        return resolver;
    }

    /**
     * com.fasterxml.jackson.dataformat
     * com.fasterxml.jackson.datatype
     *
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON));
        converters.add(converter);
    }

    /**
     * for upload
     */
    @Bean
    public CommonsMultipartResolver multipartResolver() {
        return new CommonsMultipartResolver();
    }

}
